package com.mobi.Survey;

import java.util.ArrayList;
import java.util.List;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.mobi.Survey.controller.AggregateResultPojo;
import com.mobi.Survey.controller.WebServiceIO;
import com.mobi.Survey.facades.HorizontalBarChartFacade;
import com.mobi.Survey.facades.VerticalBarChartFacade;
import com.mobi.Survey.model.AggregateResultTable;
import com.mobi.Survey.model.SurveyTable;
import com.mobi.Survey.uicomponents.ControlFactory;
import com.mobi.Survey.utils.Device;

/**
 * 
 * <p>
 * <b>Author:</b> Yahya Arshad
 * <p>
 * <b>Company:</b> Mobi Media Soft
 * <p>
 * <b> Website:</b> www.mobimediasoft.com
 * <p>
 * AggregateResultScreen.java shows aggregate result of the Survey in form of
 * Graphs
 * 
 */
public class AggregateResultScreen extends AbstractScreen
{

	long surveyId = -1;

	/**
	 * Collection to hold reference to our graph which are added on Screen we
	 * will use this Collection to hide and show our Graph
	 */
	private List<View> views = new ArrayList<View>();

	private int currentCompIndex = 0;
	private int lastComponent = 0;

	/**
	 * If not Single Screen shows current Screen i.e (5 of 7)
	 */
	private TextView txtPageNumber;
	private Button btnPrevious;
	private Button btnNext;
	/**
	 * Layout to contain Graph Views all graph Views which are generated
	 * dynamically are added in it
	 */
	private LinearLayout llGraph;
	/**
	 * if true all Survey Controls will be shown in Single Screen
	 */
	private boolean showAllControls = false;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{

		super.onCreate(savedInstanceState);
		Intent intent = getIntent();
		if (intent != null)
		{
			Bundle bundle = intent.getExtras();
			if (bundle != null)
			{
				surveyId = (Long) bundle.get("data");

			}
		}

		setTitle("Aggregate Result");
		if (surveyId <= 0)
		{
			showLongToast(Messages.INVALID_SURVEY_ID);
			finish();
		}
		new LongTask().execute();

	}

	/**
	 * 
	 * @param Callback
	 *            method when either Next or Previous button is clicked
	 */
	public void btnClick(View v)
	{

		int id = v.getId();

		if (id == R.id.btnNext)
		{
			onBtnNext();

		} else if (id == R.id.btnPrevious)
		{
			onBtnPrevious();
		}

	}

	/**
	 * Called when previous button is pressed to change the text of TextView of
	 * Current Page Number and hide and show graph
	 */
	private void onBtnPrevious()
	{
		if (!showAllControls)
		{
			StringBuilder sbTxtPageNumber = new StringBuilder();
			currentCompIndex--;
			sbTxtPageNumber.append("(");
			sbTxtPageNumber.append(currentCompIndex + 1);
			sbTxtPageNumber.append(" of ");
			sbTxtPageNumber.append(lastComponent + 1);
			sbTxtPageNumber.append(")");
			txtPageNumber.setText(sbTxtPageNumber.toString());

		}
		byte reverse = 0;
		refreshControlsVisibility(reverse);
		refreshButtonsState();

	}

	/**
	 * Called when next button is pressed to change the text of TextView of
	 * Current Page Number and hide and show graph
	 */
	private void onBtnNext()
	{
		if (!showAllControls)
		{
			StringBuilder sbTxtPageNumber = new StringBuilder();
			currentCompIndex++;

			sbTxtPageNumber.append("(");
			sbTxtPageNumber.append(currentCompIndex + 1);
			sbTxtPageNumber.append(" of ");
			sbTxtPageNumber.append(lastComponent + 1);
			sbTxtPageNumber.append(")");

			txtPageNumber.setText(sbTxtPageNumber.toString());
		}

		byte forward = 1;
		refreshControlsVisibility(forward);
		refreshButtonsState();
	}

	/**
	 * 
	 * @param direction
	 *            0 means previous button 1 means next button pressed
	 *            <p>
	 *            Called when user press next or previous button when user press
	 *            next button we hide current graph and visible next graph and
	 *            same if press previous current graph hide
	 */
	private void refreshControlsVisibility(byte direction)
	{
		if (direction == 1)
		{
			views.get(currentCompIndex).setVisibility(View.VISIBLE);
			if (currentCompIndex >= 0)
			{
				views.get(currentCompIndex - 1).setVisibility(View.GONE);

			}
		} else
		{
			views.get(currentCompIndex).setVisibility(View.VISIBLE);
			if (currentCompIndex >= 0)
			{
				views.get(currentCompIndex + 1).setVisibility(View.GONE);
			}
		}
	}

	/**
	 * Called when user press next or previous button when we reach on last
	 * control we need to disable next button so we call this method to keep
	 * track if we are on end or first
	 */
	private void refreshButtonsState()
	{
		if (currentCompIndex == 0)
		{
			btnPrevious.setEnabled(false);
		}
		if (currentCompIndex == lastComponent)
		{
			btnNext.setEnabled(false);

		}
		if (currentCompIndex > 0)
		{
			btnPrevious.setEnabled(true);
		}
		if (currentCompIndex < lastComponent)
		{
			btnNext.setEnabled(true);
		}

	}

	/**
	 * 
	 * @param componentType
	 *            Type of Control for which We want to generate Graph
	 * @param arp
	 *            Aggregate Data for that control for which we want to generate
	 *            graph
	 * @return View of graph
	 */
	private View getChart(byte componentType, AggregateResultPojo arp)
	{
		switch (componentType)
		{
		case ControlFactory.CONTROL_CHECK_BOX:

		case ControlFactory.CONTROL_RADIOGROUP:
			return new VerticalBarChartFacade(arp).setupGraph().execute(
					AggregateResultScreen.this);

		case ControlFactory.CONTROL_SPINNER:

		case ControlFactory.CONTROL_RATINGBAR:

			return new HorizontalBarChartFacade(arp).setupGraph().execute(
					AggregateResultScreen.this);
		}

		return null;
	}

	/**
	 * 
	 * @author Yahya Arshad
	 *         <p>
	 *         This private class is AsynTask executed each time activity opens
	 *         used for retrieving Aggregate result data from database and from
	 *         Internet and saving new data in local database
	 */
	private class LongTask extends AsyncTask<String, Object, Object>
	{
		ProgressDialog progressDialog = null;
		List<AggregateResultPojo> res;

		protected void onPostExecute(Object result)
		{

			super.onPostExecute(result);

			LayoutParams param = new LayoutParams(Device.getInstance()
					.getPercentWidth(1f), Device.getInstance()
					.getPercentHeight(1f));

			for (AggregateResultPojo arp : res)
			{
				View v = getChart(arp.getCtrlType(), arp);
				v.setVisibility(View.GONE);
				v.setLayoutParams(param);
				llGraph.addView(v);
				views.add(v);
			}

			lastComponent = views.size() - 1;
			if (views.size() > 0)
			{
				if (!showAllControls)
				{
					// because it is single component per screen we are making
					// first
					// item visible
					views.get(0).setVisibility(View.VISIBLE);

					refreshButtonsState();
					// setting current page number of total page
					StringBuilder sbTxtPageNumber = new StringBuilder();
					sbTxtPageNumber.append("(");
					sbTxtPageNumber.append(currentCompIndex + 1);
					sbTxtPageNumber.append(" of ");
					sbTxtPageNumber.append(lastComponent + 1);
					sbTxtPageNumber.append(")");
					txtPageNumber.setText(sbTxtPageNumber.toString());

				}

			}
			// Added else check if there is no aggregate result, next and
			// previous button should be disabled
			else
			{
				btnNext.setFocusable(false);
				btnPrevious.setFocusable(false);
				btnNext.setEnabled(false);
				btnPrevious.setEnabled(false);
			}

			progressDialog.dismiss();
			progressDialog = null;

		}

		protected void onPreExecute()
		{
			// TODO Auto-generated method stub

			super.onPreExecute();

			try
			{
				progressDialog = ProgressDialog.show(
						AggregateResultScreen.this, "", Messages.LOADING);
			} catch (Exception e)
			{
				e.printStackTrace();
			}

		}

		@Override
		protected Object doInBackground(String... params)
		{

			if (surveyId > 0)
			{
				AggregateResultTable at = new AggregateResultTable(
						AggregateResultScreen.this);

				SurveyTable st = new SurveyTable(AggregateResultScreen.this);

				String sKey = st.getSurveyKeyById(surveyId);
				st.closeDB();
				List<AggregateResultPojo> objs;

				objs = WebServiceIO.getAggregateResult(surveyId, sKey);

				if (objs != null)
				{
					at.deleteRow(surveyId);
					if (objs.size() > 0)
					{

						((AggregateResultTable) at).insertRow(objs, surveyId);

						objs.clear();
						objs = null;
					}
				}

				res = ((AggregateResultTable) at).getAggregateResult(surveyId);
				at.closeDB();
			}

			return null;

		}

	}

	@Override
	protected void initUiVars()
	{

		btnNext = (Button) findViewById(R.id.btnNext);
		btnPrevious = (Button) findViewById(R.id.btnPrevious);

		llGraph = (LinearLayout) findViewById(R.id.llGraph);

		txtPageNumber = (TextView) findViewById(R.id.txtPageNumber);

	}

	@Override
	protected int getLayoutId()
	{

		return LayoutIds.GRAPH_SCREEN;
	}

	@Override
	protected void onRelease()
	{
		views.clear();
		views = null;
	}

}
